package com.zl.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolFilterBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

import com.zl.common.Constant;
import com.zl.common.enumType.Gglb;
import com.zl.common.enumType.PublicDate;
import com.zl.common.web.SpringContextHolder;
import com.zl.entity.City;
import com.zl.entity.NewsEntity;
import com.zl.entity.Province;
import com.zl.entity.QueryEntity;
import com.zl.service.SelectorService;


/**
 * @ClassName: SearchUtils
 * @Description: es 搜索类
 * @author chxl
 * @date 2015-4-15 下午04:35:35
 * 
 */
public class SearchUtils {
	
	public static SelectorService selectorService = SpringContextHolder.getBean("selectorService");
	
	/**
	 * 综合查询方法
	 * @param queryEntity
	 * @return
	 */
	public static List<NewsEntity> search(QueryEntity queryEntity){
		List<NewsEntity> list = new ArrayList<NewsEntity>();
		SearchRequestBuilder searchBuilder = getSearchBuilder();
		String category = queryEntity.getCategory();
		String column = queryEntity.getColumn();
		
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		boolQueryBuilder.must(QueryBuilders.inQuery("_type",getTypes(category,column)));
		
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date now1 = new Date();//现在查询时间
		String endDateStr = sdf1.format(now1);
		int ordinal = Integer.parseInt(StringUtils.isBlank(queryEntity.getPublicDateValue())?"1":queryEntity.getPublicDateValue());
		Date startDate = getPubliDate(ordinal, now1);
		String startDateStr = sdf1.format(startDate);
		
		//查询范围
		String scope = queryEntity.getScope();
		String keywords = queryEntity.getKeywords();
		if (StringUtils.isNotBlank(keywords)) {
			for (String key : keywords.split(" ")) {
				if(Constant.QUERY_SCOPE_TITLE.equals(scope)){
					boolQueryBuilder.must(QueryBuilders.constantScoreQuery(QueryBuilders
							.queryStringQuery(key).field("ggbt")
							.autoGeneratePhraseQueries(true)));
				}else{
					boolQueryBuilder.must(QueryBuilders.constantScoreQuery(QueryBuilders
							.queryStringQuery(key).field("ggbt")
							.field("ggnrwb")
							.autoGeneratePhraseQueries(true)));
				}
				
			}
		}
		
		if(StringUtils.isNotBlank(queryEntity.getId())){
			boolQueryBuilder.must(QueryBuilders.queryStringQuery(
					queryEntity.getId()).field("zj"));
		}
		
		if (StringUtils.isNotBlank(queryEntity.getArea())){
			String type = queryEntity.getAreaType();
			if("1".equals(type)){
				boolQueryBuilder.must(QueryBuilders.queryStringQuery(queryEntity.getArea()).field("sfdm"));
			}else{
				boolQueryBuilder.must(QueryBuilders.queryStringQuery(queryEntity.getArea()).field("sdm"));

			}
		}
		if (startDateStr != null) {
			boolQueryBuilder.must(QueryBuilders.rangeQuery("gxsj")
					.gte(startDateStr).lte(endDateStr));
		}
		if (boolQueryBuilder.hasClauses()) {
			searchBuilder.setQuery(boolQueryBuilder);
		}
		
		searchBuilder.addSort(SortBuilders.fieldSort("gxsj").order(SortOrder.DESC));
		searchBuilder.setFrom((queryEntity.getPage()) * 10).setSize(10);
		//System.out.println(searchBuilder);
		SearchResponse response = searchBuilder.execute().actionGet();
		SearchHits hits = response.getHits();
		for (SearchHit hit : hits) {
			Map<String, Object> resource = hit.getSource();
			NewsEntity entity = new NewsEntity();
			entity.setId(resource.get("zj").toString());
			entity.setTitle(resource.get("ggbt").toString());
			
			if(resource.get("gxsj")!=null){
				String gxsj = resource.get("gxsj").toString().substring(0, 10);
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				String now = sdf.format(date);
				if (now.equals(gxsj)) {
					gxsj = "当日";
				}
				entity.setUpdateTime(gxsj);
				if(resource.get("sdm")!=null){
					City city = selectorService.getCityById(resource.get("sdm").toString());
					String areaName = city.getName();
					if(Constant.PROVINCE_GRADE.equals(city.getName())){
						Province province = selectorService.getProvinceById(city.getParentId());
						areaName = province.getName();
					}
					entity.setCity(resource.get("sdm").toString());
					entity.setArea(areaName);
				}
				if (StringUtils.isNotBlank(hit.getIndex())) {
					entity.setType(Gglb.getGglb(hit.getIndex()).getName());
					entity.setTableName(hit.getIndex());
				}
				
				list.add(entity);
			}
			
		}
		return list;
	}
	
	/**
	 * 得到索引节点名
	 * @return
	 */
	public static SearchRequestBuilder getSearchBuilder() {
		return EsUtils.getClient().prepareSearch("gg_*", "jg_*");
	}
	
	/**
	 * 得到esType 拼装类型
	 * @param category
	 * @param column
	 * @return
	 */
	public static String[] getTypes(String category,String column){
		String[] categorys = null;
		String[] columns = null;
		int categorysLength = 0;
		int columnsLength = 0;
		if(StringUtils.isNotBlank(category)){
			categorys = category.split(",");
			categorysLength = categorys.length;
		}
		if(StringUtils.isNotBlank(column)){
			columns = column.split(",");
			columnsLength = columns.length;
		}
		
		String[] types = null;
		
		if(categorysLength*columnsLength > 0){
			types = new String[categorysLength*columnsLength];
			int i = 0;
			for(String cate:categorys){
				for(String col:columns){
					types[i] = cate+"_"+col;
					i++;
				}
			}
		}else if(categorysLength==0&&columnsLength>0){
			String[] cates = {"gg","jg"};// 这边把类型暂时都写死了
			types = new String[cates.length*columnsLength];
			int i = 0;
			for(String cate:cates){
				for(String col:columns){
					types[i] = cate+"_"+col;
					i++;
				}
			}
			
		}else if(columnsLength==0&&categorysLength>0){
			String[] cols = {"gcjs","zfcg","gqcg","tdjy","kyqjy"};
			types = new String[categorysLength*columnsLength];
			int i = 0;
			for(String cate:categorys){
				for(String col:cols){
					types[i] = cate+"_"+col;
					i++;
				}
			}
			
		}else{
			String[] cates = {"gg","jg"};
			String[] cols = {"gcjs","zfcg","gqcg","tdjy","kyqjy"};
			types = new String[cates.length*cols.length];
			int i = 0;
			for(String cate:cates){
				for(String col:cols){
					types[i] = cate+"_"+col;
					i++;
				}
			}
			//String[] str = {"gg_*","jg_*"};
			//return str;
		}
		return types;
	}
	
	/**
	 * 根据发布时间
	 * @return
	 */
	public static Date getPubliDate(int ordinal,Date nowTime){
		//PublicDate publicDate = PublicDate.getDateByOrdinal(ordinal);
		Calendar now = Calendar.getInstance();
		now.setTime(nowTime);
		switch(ordinal){
			case 1: 
				now.set(Calendar.YEAR,now.get(Calendar.YEAR)-3);
				break;
			case 2: 
				now.set(Calendar.DATE,now.get(Calendar.DATE)-1);
				break;
			case 3: 
				now.set(Calendar.DATE,now.get(Calendar.DATE)-3);
				break;
			case 4: 
				now.set(Calendar.DATE,now.get(Calendar.DATE)-7);
				break;
			case 5: 
				now.set(Calendar.MONTH,now.get(Calendar.MONTH)-1);
				break;
			case 6: 
				now.set(Calendar.YEAR,now.get(Calendar.YEAR)-1);
				break;
			default:
			}
		return now.getTime();
	}
	
	
	public static List<NewsEntity> search(List<QueryEntity> querylist){
		List<NewsEntity> list = new ArrayList<NewsEntity>();
		SearchRequestBuilder searchBuilder = getSearchBuilder();
		BoolQueryBuilder boolQueryTotle = QueryBuilders.boolQuery();
		for(QueryEntity queryEntity:querylist){
			String category = queryEntity.getCategory();
			String column = queryEntity.getColumn();
			
			BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
			boolQueryBuilder.must(QueryBuilders.inQuery("_type",getTypes(category,column)));
			
			SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date now1 = new Date();//现在查询时间
			String endDateStr = sdf1.format(now1);
			int ordinal = Integer.parseInt(StringUtils.isBlank(queryEntity.getPublicDateValue())?"1":queryEntity.getPublicDateValue());
			Date startDate = getPubliDate(ordinal, now1);
			String startDateStr = sdf1.format(startDate);
			
			//查询范围
			String scope = queryEntity.getScope();
			String keywords = queryEntity.getKeywords();
			if (StringUtils.isNotBlank(keywords)) {
				for (String key : keywords.split(" ")) {
					if(Constant.QUERY_SCOPE_TITLE.equals(scope)){
						boolQueryBuilder.must(QueryBuilders.constantScoreQuery(QueryBuilders
								.queryStringQuery(key).field("ggbt")
								.autoGeneratePhraseQueries(true)));
					}else{
						boolQueryBuilder.must(QueryBuilders.constantScoreQuery(QueryBuilders
								.queryStringQuery(key).field("ggbt")
								.field("ggnrwb")
								.autoGeneratePhraseQueries(true)));
					}
					
				}
			}
			
			if(StringUtils.isNotBlank(queryEntity.getId())){
				boolQueryBuilder.must(QueryBuilders.queryStringQuery(
						queryEntity.getId()).field("zj"));
			}
			
			if (StringUtils.isNotBlank(queryEntity.getArea())){
				String type = queryEntity.getAreaType();
				if("1".equals(type)){
					boolQueryBuilder.must(QueryBuilders.queryStringQuery(queryEntity.getArea()).field("sfdm"));
				}else{
					boolQueryBuilder.must(QueryBuilders.queryStringQuery(queryEntity.getArea()).field("sdm"));

				}
			}
			if (startDateStr != null) {
				boolQueryBuilder.must(QueryBuilders.rangeQuery("gxsj")
						.gte(startDateStr).lte(endDateStr));
			}
			
			boolQueryTotle.should(boolQueryBuilder);
		}
		if (boolQueryTotle.hasClauses()) {
			searchBuilder.setQuery(boolQueryTotle);
		}
		
		searchBuilder.addSort(SortBuilders.fieldSort("gxsj").order(SortOrder.DESC));
		searchBuilder.setFrom((querylist.get(0).getPage()) * 10).setSize(10);
		//System.out.println(searchBuilder);
		SearchResponse response = searchBuilder.execute().actionGet();
		SearchHits hits = response.getHits();
		for (SearchHit hit : hits) {
			Map<String, Object> resource = hit.getSource();
			NewsEntity entity = new NewsEntity();
			entity.setId(resource.get("zj").toString());
			entity.setTitle(resource.get("ggbt").toString());
			
			if(resource.get("gxsj")!=null){
				String gxsj = resource.get("gxsj").toString().substring(0, 10);
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				String now = sdf.format(date);
				if (now.equals(gxsj)) {
					gxsj = "当日";
				}
				entity.setUpdateTime(gxsj);
				if(resource.get("sdm")!=null){
					City city = selectorService.getCityById(resource.get("sdm").toString());
					String areaName = city.getName();
					if(Constant.PROVINCE_GRADE.equals(city.getName())){
						Province province = selectorService.getProvinceById(city.getParentId());
						areaName = province.getName();
					}
					entity.setCity(resource.get("sdm").toString());
					entity.setArea(areaName);
				}
				if (StringUtils.isNotBlank(hit.getIndex())) {
					entity.setType(Gglb.getGglb(hit.getIndex()).getName());
					entity.setTableName(hit.getIndex());
				}
				
				list.add(entity);
			}
			
		}
		return list;
	}
	
	
	public static List<NewsEntity> selectEsByWz(String wzzj){
		List<NewsEntity> list = new ArrayList<NewsEntity>();
		SearchRequestBuilder searchBulider = EsUtils.getClient().prepareSearch("gg_*", "jg_*");
		BoolFilterBuilder boolFilterBuilder = FilterBuilders.boolFilter();
		if (StringUtils.isNotBlank(wzzj)) {
			boolFilterBuilder.must(FilterBuilders.termFilter("wzzj", wzzj));
		}
		
		if (boolFilterBuilder.hasClauses()) {
			searchBulider.setPostFilter(boolFilterBuilder);
		}
		searchBulider.addSort(SortBuilders.fieldSort("gxsj").order(
				SortOrder.DESC));
		searchBulider.setFrom(0).setSize(6);
		SearchResponse response = searchBulider.execute().actionGet();
		SearchHits hits = response.getHits();
		for (SearchHit hit : hits) {
			Map<String, Object> resource = hit.getSource();
			NewsEntity entity = new NewsEntity();
			entity.setId(resource.get("zj").toString());
			entity.setTitle(resource.get("ggbt").toString());
			
			if(resource.get("gxsj")!=null){
				String gxsj = resource.get("gxsj").toString().substring(0, 10);
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				String now = sdf.format(date);
				if (now.equals(gxsj)) {
					gxsj = "当日";
				}
				entity.setUpdateTime(gxsj);
				if(resource.get("sdm")!=null){
					City city = selectorService.getCityById(resource.get("sdm").toString());
					String areaName = city.getName();
					if(Constant.PROVINCE_GRADE.equals(city.getName())){
						Province province = selectorService.getProvinceById(city.getParentId());
						areaName = province.getName();
					}
					entity.setCity(resource.get("sdm").toString());
					entity.setArea(areaName);
				}
				if (StringUtils.isNotBlank(hit.getIndex())) {
					entity.setType(Gglb.getGglb(hit.getIndex()).getName());
					entity.setTableName(hit.getIndex());
				}
				
				list.add(entity);
			}
		}
		return list;
	}
}
